﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Xml.XPath;
using System.Collections;

namespace TibcoMessageAdmin
{

   public  struct nSpace
    {
       public string Prefix;
       public string Name;
       public string NameSpace;
       public string NodeName;
    }


    public partial class xPath : Form
    {
        string lastPrefix = string.Empty;
        string _xml = "";
        bool _cancelled = false;
        string nameSpaces = "";
        List<nSpace> nSpaceList = new List<nSpace>();
        Hashtable prfx = new Hashtable();
      //  ArrayList nSpaceList = new ArrayList(); 
        static Random _random = new Random();
        public string xml
        {
            get
            {
                return _xml;
            }

            set
            {
                _xml = value;
            }
        }

        public xPath()
        {
            InitializeComponent();
        }

        private void xPath_Load(object sender, EventArgs e)
        {
            xmlTreeView.Nodes.Clear();

            XmlDocument document = new XmlDocument();
            document.LoadXml(_xml);


          


            //loop through the top nodes  
            foreach (XmlNode node in document)
            {
                GetNamespace(node);
                TreeNode treeNode = XmlNode2TreeNode(node);
                GetAttributes(node, treeNode);
                treeNode.Text = FormatName(node);
                xmlTreeView.Nodes.Add(treeNode);
            }

            xmlTreeView.ExpandAll();  
        }


        private string GetNextPrefix()
        {           
            string key = GetLetter();
            while (prfx.ContainsKey(key))
            {
                key = GetLetter();                
            }
            prfx.Add(key, key);
            return key;

        }
       
        public static string  GetLetter()
        {
            // This method returns a random lowercase letter.
            // ... Between 'a' and 'z' inclusize.
            int num = _random.Next(0, 26); // Zero to 25
            int num2 = _random.Next(0, 26); // Zero to 25
            char let = (char)('a' + num);
            char let1 = (char)('a' + num2);
            return let.ToString() + let1.ToString() ;
        }

        private TreeNode XmlNode2TreeNode(XmlNode parentNode)
        {
            TreeNode treeNode = new TreeNode();
           
            foreach (XmlNode childNode in parentNode.ChildNodes)
            {

                GetNamespace(childNode);

                

             


                if (childNode.NodeType == XmlNodeType.Element)
                {
                    TreeNode childTreeNode = new TreeNode();

                    if (childNode.ChildNodes.Count > 0)
                        childTreeNode = XmlNode2TreeNode(childNode);

                    childTreeNode.Text = FormatName(childNode);
                    GetAttributes(childNode, childTreeNode);
                    treeNode.Nodes.Add(childTreeNode);
                }
            }

            return treeNode;
        }

        private void GetNamespace(XmlNode childNode)
        {
            if (childNode.Attributes != null)
            {
                foreach (XmlAttribute attr in childNode.Attributes)
                {
                    nSpace np = nSpaceList.FirstOrDefault(x => x.NameSpace == attr.Value);
                    if ((np.NameSpace == null && !string.IsNullOrEmpty(attr.Value)) || (np.NameSpace != null && np.Prefix != attr.LocalName))
                    {

                        nSpace np1 = nSpaceList.FirstOrDefault(x => x.Prefix == attr.LocalName && attr.Value == x.NameSpace  );
                        if (np1.Prefix == null)
                        {
                            nSpace np2 = nSpaceList.FirstOrDefault(x => x.Prefix == attr.LocalName);

                            if (np2.Prefix != null)
                            {
                                nSpace n1 = new nSpace();
                                n1.Prefix = GetNextPrefix();
                                // n1.Name = childNode.Name;
                                n1.NameSpace = attr.Value;
                                n1.NodeName = (attr).OwnerElement.LocalName;
                                nSpaceList.Add(n1);                            
                            }
                            else
                            {
                                nSpace n1 = new nSpace();
                                if (string.IsNullOrEmpty(attr.LocalName))
                                {
                                    n1.Prefix = GetNextPrefix();
                                }
                                else
                                {
                                    n1.Prefix = attr.LocalName;
                                }
                                // n1.Name = childNode.Name;
                                n1.NameSpace = attr.Value;
                                n1.NodeName = (attr).OwnerElement.LocalName;
                                nSpaceList.Add(n1);
                            }
                        }                     
                    }
                 


                }
            }


        }
        private string FormatName(XmlNode node)
        {
            string fullName = "<" + node.Name;

            if (node.InnerText != "")
                fullName += ">" + node.InnerText + "</" + node.Name + ">";
            else
                fullName += ">";

            return fullName;
        }

        private void GetAttributes(XmlNode node, TreeNode treeNode)
        {
            if (node.Attributes != null)
            {
                ListViewItem[] attributes = new ListViewItem[node.Attributes.Count];

                for (int i = 0; i < node.Attributes.Count; i++)
                {
                    attributes[i] = new ListViewItem(new string[] {  
                    node.Attributes[i].Name, node.Attributes[i].Value });
                }

                treeNode.Tag = attributes;
            }
        }

        private void xmlTreeView_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            //attributesListView.Items.Clear();
            //if (e.Node.Tag != null)
            //{
            //    attributesListView.Items.AddRange((ListViewItem[])e.Node.Tag);
            //}
        }

        private void xmlTreeView_NodeMouseClick_1(object sender, TreeNodeMouseClickEventArgs e)
        {
            string  xPathCmd = string.Empty  ;
         
            int fistp = 0 ;
            int findp = 0 ;
            TreeNode node  = e.Node ;

            textBox1.Text  ="";

            foreach (nSpace  c in nSpaceList )
            {
                textBox1.Text += string.Format("declare namespace {0}=\"{1}\"; {2} ", c.Prefix, c.NameSpace, Environment.NewLine );  
                
            }


            xPathCmd = GetXmlTag(node.Text);

            node = node.Parent ;

            while (node.Parent != null)
            {
                    xPathCmd  = GetXmlTag(node.Text) + "/" + xPathCmd;
                    node = node.Parent;
            }
            xPathCmd = "/" +  GetXmlTag(node.Text) + "/" + xPathCmd;
            //textBox1.Text = nameSpaces;
            textBox1.Text += Environment.NewLine; 
            textBox1.Text += xPathCmd.Replace(">","").Replace("<","")  ;
            


        }

        private string GetXmlTag(string fText)
        {
           string tNode =  fText.Substring(0, fText.IndexOf(">") + 1);
           string[] tmp = tNode.Split(":".ToCharArray());
           string nodeName = "";
            
           if (tmp.Length > 0)
           {
               nodeName = tmp[1].Replace(">",""); 

           }
           nSpace np = nSpaceList.FirstOrDefault(x => x.NodeName == nodeName);
           if (np.NameSpace != null)
           {
              // lastPrefix = np.Prefix;
               nodeName = np.Prefix + ":" + nodeName;
           }
           else
           {
                   nodeName = tmp[0].Replace("<","")  + ":" + nodeName;
               

           }
           return nodeName;
            

        }

    }

}
